from faceRecognition import faceRec
from flask import Flask, request
from flask_limiter.util import get_remote_address
from flask_restplus import Resource, Api
from flask_limiter import Limiter
import base64
from util import R
from util import compress

app = Flask(__name__)
app.config.from_pyfile('conf/config.ini')
limiter = Limiter(
    app,
    key_func=get_remote_address,
    default_limits=["10 per minute"]
)

api = Api(app)


@app.before_request
def process_request( *args, **kwargs):
    blackList = []
    with open('conf/blackList', 'r') as f:
        for line in f.readlines():
            blackList.append(line.strip())
    if request.remote_addr in blackList:
        code = 201
        msg = {'English': 'Your IP address has no Authority', '中文': '你的ip没有访问权限'}
        return R.ifm(code, msg)
    pass


@app.after_request
def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'  # 跨域
    return response


@app.errorhandler(429)
def ratelimit_handler(e):
    code = 429
    msg = {'English': 'Your visit frequency is too high. Please try again later', '中文': '您的访问频率过高，情稍后再试'}
    return R.ifm(code, msg)


@app.errorhandler(404)
def nofound_handler(e):
    return R.nofound


@app.errorhandler(500)
def error_handler(e):
    return R.error


@app.errorhandler(405)
def methodNotAllowed_handler(e):
    return R.methodNotAllowed


rectangles = api.namespace('rectangles', '检测图片中人脸以及五官位置')
@rectangles.route('.form')
class ApiRectanglesForm(Resource):
    def post(self):
        try:
            img = request.files.get('faceImg')
            rectangles = faceRec.get_rectangles(img.read())
            personNum = len(rectangles)
            for i, rectangle in enumerate(rectangles):
                rectangle = {'topLeftCorner': [rectangle[0], rectangle[1]],
                              'topRightCorner': [rectangle[2], rectangle[3]],
                              'width': abs(rectangle[2] - rectangle[0]),
                              'height': abs(rectangle[3]-rectangle[1]),
                              'facialFeatures': [[rectangle[4], rectangle[5]], [rectangle[6], rectangle[7]],
                                                 [rectangle[8], rectangle[9]], [rectangle[10], rectangle[11]],
                                                 [rectangle[12], rectangle[13]]]
                          }
                rectangles[i] = rectangle
            msg = {'personNum':personNum, 'rectangles': rectangles}
            return R.ok(msg)
        except:
            return R.error

@rectangles.route('.json')
class ApiRectanglesJson(Resource):
    def post(self):
        try:
            img = request.json.get('faceImg')
            img = base64.b64decode(img)
            rectangles = faceRec.get_rectangles(img)
            personNum = len(rectangles)
            for i, rectangle in enumerate(rectangles):
                rectangle = {'topLeftCorner': [rectangle[0], rectangle[1]],
                              'topRightCorner': [rectangle[2], rectangle[3]],
                              'width': abs(rectangle[2] - rectangle[0]),
                              'height': abs(rectangle[3]-rectangle[1]),
                              'facialFeatures': [[rectangle[4], rectangle[5]], [rectangle[6], rectangle[7]],
                                                 [rectangle[8], rectangle[9]], [rectangle[10], rectangle[11]],
                                                 [rectangle[12], rectangle[13]]]
                          }
                rectangles[i] = rectangle
            msg = {'personNum':personNum, 'rectangles': rectangles}
            return R.ok(msg)
        except:
            return R.error


recognize = api.namespace('recognize', '提取特征向量')
@recognize.route('.form')
class ApiRecognizeForm(Resource):
    def post(self):
        try:
            img = request.files.get('faceImg')
            features = faceRec.get_features(img.read())
            features = compress.en(features)
            msg = {'features': features}
            return R.ok(msg)
        except:
            return R.error


@recognize.route('.json')
class ApiRecognizeJson(Resource):
    def post(self):
        try:
            img = request.json.get('faceImg')
            img = base64.b64decode(img)
            features = faceRec.get_features(img)
            features = compress.en(features)
            msg = {'features': features}
            return R.ok(msg)
        except:
            return R.error


compare = api.namespace('compare', '比对特征向量')


@compare.route('.json')
class ApiCompareJson(Resource):
    def post(self):
        try:
            features1 = request.json.get('features1')
            features2 = request.json.get('features2')
            features1 = compress.de(features1)
            features2 = compress.de(features2)
            dist = faceRec.compare_features(features1, features2)
            msg = {'distance': dist, 'ifm': 'The smaller the distance, the higher the similarity'}
            return R.ok(msg)
        except:
            return R.error

@compare.route('All.json')
class ApiCompareAllJson(Resource):
    def post(self):
        try:
            featuresList = request.json.get('featuresList')
            features = request.json.get('features')
            for i, e in enumerate(featuresList):
                featuresList[i] = compress.de(e)
            features = compress.de(features)
            distList = faceRec.compareAll_features(featuresList, features)
            msg = {'distanceList': distList, 'ifm': 'The smaller the distance, the higher the similarity'}
            return R.ok(msg)
        except:
            return R.error



if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port='9000')
